package cn.bytengine.stem.contexts;

import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.map.MapUtil;

import java.util.Map;

/**
 * 不支持修改数据的核心上下文。它不支持父级上下文。
 */
public class ImmutableCoreContext extends InternalCoreContext {

    private ImmutableCoreContext() {
        super();
    }

    private ImmutableCoreContext(Map<String, Object> data) {
        super(data);
    }

    /**
     * 该方法不支持此操作，并抛出{@link UnsupportedOperationException}异常
     *
     * @param key   上下文对应数据的key
     * @param value 上下文对应key的数据
     * @return 当前上下文实例
     * @throws UnsupportedOperationException 不支持调用
     */
    @Override
    public ImmutableCoreContext set(String key, Object value) throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    /**
     * 该方法不支持此操作，并抛出{@link UnsupportedOperationException}异常
     *
     * @param data 要设置的Map数据内容
     * @return 当前上下文实例
     * @throws UnsupportedOperationException 不支持调用
     */
    @Override
    public ImmutableCoreContext set(Map<String, Object> data) throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    /**
     * 该方法不支持此操作，并抛出{@link UnsupportedOperationException}异常
     *
     * @param key 上下文对应数据的key
     * @return 当前上下文实例
     * @throws UnsupportedOperationException 不支持调用
     */
    @Override
    public ImmutableCoreContext remove(String key) throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    /**
     * 创建不可修改上下文构建器实例
     *
     * @return 不可修改上下文实例，详见{@link Builder}和{@link ImmutableContextBuilder}
     */
    public static Builder builder() {
        return new ImmutableContextBuilder();
    }

    /**
     * 根据初始化数据创建不可修改上下文构建器实例
     *
     * @param data 上下文初始化数据
     * @return 不可修改上下文实例，详见{@link Builder}和{@link ImmutableContextBuilder}
     */
    public static Builder builder(Map<String, Object> data) {
        return new ImmutableContextBuilder().set(data);
    }

    /**
     * 根据初始化数据，创建不可修改上下文实例
     *
     * @param data 上下文初始化数据
     * @return 不可修改上下文实例，详见{@link Builder}和{@link ImmutableContextBuilder}
     */
    public static ImmutableCoreContext create(Map<String, Object> data) {
        return new ImmutableCoreContext(data);
    }

    /**
     * 不可修改上下文构建器
     */
    public interface Builder extends Setter<Builder> {
        /**
         * 添加上下文数据
         *
         * @param key   上下文对应数据的key
         * @param value 上下文对应key的数据
         * @return 当前构建器实例对象，支持链式调用
         */
        Builder set(String key, Object value);

        /**
         * 通过Map修改数据内容
         *
         * @param map 修改数据集合
         * @return 当前构建器实例对象，支持链式调用
         */
        Builder set(Map<String, Object> map);

        /**
         * 清空已有数据
         *
         * @return 当前构建器实例对象，支持链式调用
         */
        Builder clear();

        /**
         * 创建不可变上下文实例
         *
         * @return 不可变上下文实例，详见{@link ImmutableCoreContext}
         */
        ImmutableCoreContext build();
    }

    /**
     * 不可变上下文构建实现，基于{@link MapBuilder}实现
     */
    static class ImmutableContextBuilder implements Builder {
        private MapBuilder<String, Object> builder;

        private ImmutableContextBuilder() {
            builder = MapUtil.builder();
        }

        public Builder set(String o, Object o2) {
            builder.put(o, o2);
            return this;
        }

        public Builder set(Map<String, Object> map) {
            builder.putAll(map);
            return this;
        }

        public Builder clear() {
            builder.clear();
            return this;
        }

        public ImmutableCoreContext build() {
            return new ImmutableCoreContext(builder.build());
        }
    }
}
